% Y = ELEMENTREDUCE(X)  Reduce a sum of GF elements into a single GF 
%                       element.
%
%   Inputs
%           X    A vector of powers of GF elements to be reduced.  No
%                particular order is required.  All elements must be
%                nonnegative integers between 0 and 2^m - 1
%
%   Outputs
%           
%

function z = elementReduce(x)

    global m add_one

    % Check for zeros and remove them
    if ~isempty(find(x < 0))
        x(find(x < 0)) = [];
    end

    % Reduce any elements which have exponents greater than or equal to 2^m - 1
    x = mod(x, 2^m-1);

    % Sort the addends into descending order
    x = sort(x, 'descend' );

    % Combine any two terms which are the same power of alpha
    z = [];

    while length(x) >= 1

        if length(x) == 1
            z = [z x];
            break;
        elseif x(1) == x(2)
            if length(x) == 2
                break;
            else
                x = x(3:end);
            end
        else
            z = [z x(1)];
            x = x(2:end);
        end
    end

    %Loop invariant: x contains
    % a^n1 + a^n2 + ...  where n1 > n2 > n3 ...
    while length(z) > 1

        %Combine the two high-order terms
        diff = z(1) - z(2);
        added = add_one(diff,2);
        z(2) = elementMult(added,z(2)); 
        z = z(2:end);

    end

    if isempty(z)
        z = -1;
    end
    
end
